﻿using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;

namespace Firefly.Framework.Input
{
    public abstract class HumanInterfaceDevice<S> : IHumanInterfaceDevice<S>
    {
        public HumanInterfaceDevice()
        {
            Enabled = true;
            UpdateOrder = 0;
            InputMaps = new List<IInputMap>();
        }

        #region IHumanInterfaceDevice Members

        public event EventHandler<StateChangedEventArgs<S>> StateChanged;

        public DeviceType DeviceType { get; protected set; }
        public S CurrentState { get; protected set; }
        public S PreviousState { get; protected set; }
        public List<IInputMap> InputMaps { get; protected set; }

        public virtual void RegisterInputMap(IInputMap map)
        {
            if (InputMaps != null)
            {
                InputMaps.Add(map);
                InputMaps.Sort(new InputMapUpdateOrderComparer());
            }
        }

        protected void NotifyStateChanged(StateChangedEventArgs<S> e)
        {
            EventHandler<StateChangedEventArgs<S>> handler = StateChanged;

            if (handler != null)
            {
                handler(this, e);
            }
        }

        #endregion

        #region IUpdateable Members

        public event EventHandler EnabledChanged;
        public event EventHandler UpdateOrderChanged;

        private bool _enabled;
        private int _updateOrder;

        public bool Enabled
        {
            get { return _enabled; }
            set
            {
                if (value != _enabled)
                {
                    _enabled = value;
                    NotifyEnabledChanged();
                }
            }
        }
        public int UpdateOrder
        {
            get { return _updateOrder; }
            set
            {
                if (value != _updateOrder)
                {
                    _updateOrder = value;
                    NotifyUpdateOrderChanged();
                }
            }
        }

        protected void NotifyEnabledChanged()
        {
            EventHandler handler = EnabledChanged;

            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }

        protected void NotifyUpdateOrderChanged()
        {
            EventHandler handler = UpdateOrderChanged;

            if (handler != null)
            {
                handler(this, new EventArgs());
            }
        }

        public abstract void Update(GameTime gameTime);

        #endregion

        #region IHumanInterfaceDevice<S> Members


        S IHumanInterfaceDevice<S>.CurrentState
        {
            get { throw new NotImplementedException(); }
        }

        S IHumanInterfaceDevice<S>.PreviousState
        {
            get { throw new NotImplementedException(); }
        }

        #endregion
    }
}
